package cn.netuo.bumbersoll.util;

import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.widget.ImageView;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.UUID;

import cn.netuo.bumbersoll.App;
import cn.netuo.bumbersoll.BizConstant;
import cn.netuo.bumbersoll.entity.Action;
import cn.netuo.bumbersoll.entity.Cmd;
import cn.netuo.bumbersoll.entity.MqttFromS;
import cn.netuo.bumbersoll.entity.VideoAd;
import cn.netuo.bumbersoll.helper.ble.ClsUtils;
import cn.netuo.bumbersoll.upgrade.Version;
import lib.grasp.util.AppUtil;
import lib.grasp.util.L;
import lib.grasp.util.ScreenUtil;

/**
 * Created by JS_grasp on 2019/3/18.
 */
public class BsUtil {

    /** 获取MQTT订阅主题 */
    public static String getMqttTopic(Context context){
        String str = BizConstant.ARG_MQTT_TOPIC;
        if(!TextUtils.isEmpty(BizConstant.ARG_MQTT_TOPIC) && BizConstant.ARG_MQTT_TOPIC.endsWith("send")){
            str = str.substring(0, str.length() - 4);
        }
        return str;
    }

    /** 获取设备id */
    public static String getDeviceId(AppCompatActivity activity){
        String mac = Settings.System.getString(activity.getContentResolver(), Settings.System.ANDROID_ID);
        if(TextUtils.isEmpty(mac)) {
            mac = AppUtil.getIMEI(activity);
        }
        return mac;
    }

    /** 获取业务id */
    public static String getBizId(Context context){
        return App.getApp().getTableMgr().getTbArg().queryByArgName(BizConstant.ARG_BIZ_ID_KEY);
    }

    /** 获取业务id */
    public static String getBtId(Context context){
        return App.getApp().getTableMgr().getTbArg().queryByArgName(BizConstant.ARG_BLE_ADDR_KEY);
    }

    /** 获取区域id */
    public static String getAreaId(Context context){
        return App.getApp().getTableMgr().getTbArg().queryByArgName(BizConstant.ARG_AREA_ID_KEY);
    }

    /** 获取Bugly是否开发设备 */
    public static boolean getBuglyIsDevelopDev(Context context){
        String buglyIsDevelopDev = App.getApp().getTableMgr().getTbArg().queryByArgName(BizConstant.ARG_BUGLY_IS_DEVELOP_DEV);
        return TextUtils.equals(buglyIsDevelopDev, "1");
    }

    /** 获取Bugly是否允许Log调试 */
    public static boolean getBuglyEnableLog(Context context){
        String buglyEnableLog = App.getApp().getTableMgr().getTbArg().queryByArgName(BizConstant.ARG_BUGLY_ENABLE_LOG);
        return TextUtils.equals(buglyEnableLog, "1");
    }

    /** 初始化低电模式 */
    public static void resetLowPowerMode(Context context){
        int powerRate = App.getApp().getBatteryReceiver().getBatteryLeftRate(context);
        // 初始化低电模式
        if (powerRate > 99) {   // 过充了(人为原因)
            BizConstant.IS_NOW_IN_LOWPOWER_MODE = false;
        } else if (powerRate < 1) {   // 空电了(人为原因)
            BizConstant.IS_NOW_IN_LOWPOWER_MODE = true;
        } else if (powerRate > BizConstant.BATTERY_MAX) {       // 充满了, 停止充电, 退出低电模式
            BizConstant.IS_NOW_IN_LOWPOWER_MODE = false;
        } else if (powerRate < BizConstant.BATTERY_LIMIT) {     // 没电了, 继续充电, 进入底电模式
            BizConstant.IS_NOW_IN_LOWPOWER_MODE = true;
        } else if (powerRate > BizConstant.BATTERY_MIN) {       // 电够用了, 继续充电, 退出低电模式
            BizConstant.IS_NOW_IN_LOWPOWER_MODE = false;
        } else if (powerRate <= BizConstant.BATTERY_MIN) {      // 电不满, 开始充电
            BizConstant.IS_NOW_IN_LOWPOWER_MODE = false;
        }
    }

    public static void doOnPadPower(Context context, float powerRate){
        L.logOnly("检测电量:" + powerRate);
        if(powerRate > BizConstant.BATTERY_MAX){   // 充满了, 停止充电, 退出低电模式
            if(BizConstant.IS_NOW_IN_LOWPOWER_MODE) {
                BizConstant.IS_NOW_IN_LOWPOWER_MODE = false;
                doSwitchLowPower(context);  // 控制播放/屏幕亮不亮
            }

            if(App.getApp().getBatteryReceiver().isBatteryCharging(context)) {  // 若在充电
                doChangePadChargeState(context, false);// 请停止充电
            }
        }
        else if(powerRate < BizConstant.BATTERY_LIMIT && powerRate > 0){   // 没电了, 继续充电, 进入底电模式
            if(!BizConstant.IS_NOW_IN_LOWPOWER_MODE) {
                BizConstant.IS_NOW_IN_LOWPOWER_MODE = true;
                doSwitchLowPower(context);  // 控制播放/屏幕亮不亮
            }

            if(!App.getApp().getBatteryReceiver().isBatteryCharging(context)) { //若没在充电
                doChangePadChargeState(context, true);                          // 请充电
            }
        }
        else if(powerRate > BizConstant.BATTERY_MIN){  // 电够用了, 继续充电, 退出低电模式
            if(BizConstant.IS_NOW_IN_LOWPOWER_MODE) {
                BizConstant.IS_NOW_IN_LOWPOWER_MODE = false;
                doSwitchLowPower(context);  // 控制播放/屏幕亮不亮
            }
//
//            if(!App.getApp().getBatteryReceiver().isBatteryCharging(context)) { // 若没在充电
//                doChangePadChargeState(context, true);                      // 请充电
//            }
        }
        else if(powerRate <= BizConstant.BATTERY_MIN && powerRate != 0){  // 电不满, 开始充电
//            if(BizConstant.IS_NOW_IN_LOWPOWER_MODE) {
//                BizConstant.IS_NOW_IN_LOWPOWER_MODE = false;
//                doSwitchLowPower(context);  // 控制播放/屏幕亮不亮
//            }

            if(!App.getApp().getBatteryReceiver().isBatteryCharging(context)) { //若没在充电
                doChangePadChargeState(context, true);                          // 请充电
            }
        }
    }

    /** 进入/退出低电模式 */
    private static void doSwitchLowPower(Context context){
        App.getApp().getLocalBroadMgr().broadAction(BizConstant.BROAD_LOW_POWER_CHANGED);
    }

    /** 控制pad充电 */
    private static void doChangePadChargeState(Context context, boolean targetChargingStatus){
        if(App.getApp().getBLEHelper() == null) return;
        App.getApp().getBLEHelper().addAction(BsUtil.getTestCmd(context, targetChargingStatus ? BizConstant.REQUEST_NAME_PAD_POWERON : BizConstant.REQUEST_NAME_PAD_POWEROFF));
    }

    public static void createQRcodeImage(String url, ImageView iv) {
        int w = iv.getWidth();
        int h = iv.getHeight();
        if(w == 0 || h == 0)return;
        try {
            //判断URL合法性
            if (url == null || "".equals(url) || url.length() < 1) {
                return;
            }
            Hashtable<EncodeHintType, String> hints = new Hashtable<>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            //图像数据转换，使用了矩阵转换
            BitMatrix bitMatrix = new QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, w, h, hints);
            int[] pixels = new int[w * h];
            //下面这里按照二维码的算法，逐个生成二维码的图片，
            //两个for循环是图片横列扫描的结果
            for (int y = 0; y < h; y++) {
                for (int x = 0; x < w; x++) {
                    if (bitMatrix.get(x, y)) {
                        pixels[y * w + x] = 0xff000000;
                    }
                    else {
                        pixels[y * w + x] = 0x00ffffff;
                    }
                }
            }
            //生成二维码图片的格式，使用ARGB_8888
            Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_4444);
            bitmap.setPixels(pixels, 0, w, 0, 0, w, h);
            //显示到我们的ImageView上面
            iv.setImageBitmap(bitmap);
        }
        catch (WriterException e) {
            e.printStackTrace();
        }
    }

    /** String列表转String */
    public static String stringList2String(List<String> list){
        if(list == null || list.size() == 0) return "";
        return new Gson().toJson(list);
    }

    /** String转String列表 */
    public static ArrayList<String> string2StringList(String str){
        if(TextUtils.isEmpty(str)) return new ArrayList<>();
        Type type = new TypeToken<ArrayList<String>>() {}.getType();
        return new Gson().fromJson(str, type);
    }

    /** 关掉APP */
    public static void stopApp(){
        System.exit(1);
        android.os.Process.killProcess(android.os.Process.myPid());
    }

    /** 将MQTT的消息转化为具体命令,并加入待执行列表 */
    public static void addActionFromMsg(String msg){
        try{
            MqttFromS<Action> temp = new Gson().fromJson(msg, new TypeToken<MqttFromS<Action>>() {}.getType());
            if(temp == null || temp.data == null || TextUtils.isEmpty(temp.data.requestName)) return;
            temp.data.cmd = getCmdFromDbByRequestName(temp.data.requestName);
            App.getApp().getBLEHelper().addAction(temp);
        }
        catch (Exception e){
            L.logOnly("服务器数据出错");
        }
    }

    /** 将MQTT的消息转化为具体命令,并加入待执行列表 */
    public static void addOrRefreshCmd(String msg) throws Exception {
        MqttFromS<List<Cmd>> temp = new Gson().fromJson(msg, new TypeToken<MqttFromS<List<Cmd>>>() {}.getType());
        if(temp == null || temp.data == null || temp.data.size() == 0) return;
        for(Cmd cmd : temp.data) App.getApp().getTableMgr().getTbCmd().importArg(cmd);
    }

    /** 通过给定的requestName换取Cmd实体 */
    @Nullable
    public static Cmd getCmdFromDbByRequestName(String requestName){
        if(TextUtils.isEmpty(requestName)) return null;
        return App.getApp().getTableMgr().getTbCmd().queryCmdByArgName(requestName);
    }


    /** 将MQTT的消息转化为具体命令,并加入待执行列表 */
    public static void doOnNewVideoAdTask(String msg){
        // 先对收到的广告列表进行处理
        // 0. 如果列表为空, 则删除所有就的元祖, 停止播放所有视频
        // 1. 如果库里最新的一批视频中有, 那就更新下indbtime
        // 2. 如果库里最新的一批视频没有, 那就写入
        // 3. 删除所有旧的元祖
        try{
            MqttFromS<List<VideoAd>> listFromS = new Gson().fromJson(msg, new TypeToken<MqttFromS<List<VideoAd>>>() {}.getType());
            if(listFromS == null || listFromS.data == null) return;

            App.getApp().getTableMgr().getTbVideoAd().deleteEarly();

            long newInDbTime = System.currentTimeMillis() / 1000;
            for(VideoAd videoAd : listFromS.data){
                videoAd.indbtime    = newInDbTime;
                videoAd.state       = App.getApp().getTableMgr().getTbVideoAd().queryState(videoAd.url);
                App.getApp().getTableMgr().getTbVideoAd().updateOrInsert(videoAd);
            }

            App.getApp().getLocalBroadMgr().broadAction(BizConstant.BROAD_VIDEO_TASK);
        }
        catch (Exception e){
            L.logOnly("服务器数据出错");
        }
    }



    /** 将MQTT的消息转化为具体调节音量命令 */
    public static int parseNewVolTask(String msg){
        try{
            MqttFromS<Integer> listFromS = new Gson().fromJson(msg, new TypeToken<MqttFromS<Integer>>() {}.getType());
            if(listFromS == null || listFromS.data == null) return -1;
            return listFromS.data;
        }
        catch (Exception e){
            L.logOnly("服务器数据出错");
            return -1;
        }
    }

    /** 将MQTT的消息转化为版本升级命令 */
    public static Version parseNewVersion(String msg){
        try{
            MqttFromS<Version> listFromS = new Gson().fromJson(msg, new TypeToken<MqttFromS<Version>>() {}.getType());
            if(listFromS == null || listFromS.data == null) return null;
            return listFromS.data;
        }
        catch (Exception e){
            L.logOnly("服务器数据出错");
            return null;
        }
    }

    /** 去掉蓝牙匹配输入 */
    public static void doEscapePin(Intent intent, MqttFromS<Action> mActionMqttFromS, BroadcastReceiver broadcastReceiver){
        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
            try {
                /**
                 * cancelPairingUserInput（）取消用户输入密钥框，
                 * 个人觉得一般情况下不要和setPin（setPasskey、setPairingConfirmation、
                 * setRemoteOutOfBandData）一起用，
                 * 这几个方法都会remove掉map里面的key:value（<<<<<也就是互斥的>>>>>>）。
                 */
                L.logOnly("建立配对关系[免弹窗输入]");
                //1.确认配对
                //ClsUtils.setPairingConfirmation(device.getClass(), device, true);
                ClsUtils.setPin(device.getClass(), device, mActionMqttFromS.data.btPairPWD); // 手机和蓝牙采集器配对
                //ClsUtils.setPasskey(device.getClass(), device, strPsw);
                //ClsUtils.cancelPairingUserInput(device.getClass(), device); //一般调用不成功，前言里面讲解过了
                L.logOnly("配对成功");
                broadcastReceiver.abortBroadcast();   //如果没有将广播终止，则会出现一个一闪而过的配对框。
            } catch (Exception e) {
                L.logOnly("反射异常："+e);
            }
        }
    }


    /** 存入上次加载数据的日期 */
    public static void saveLastLoadDate(Context ctx, String argKey, long timeStamp){
        Date dateServer = new Date(timeStamp);
        Calendar calendar = Calendar.getInstance();                             //日历对象
        calendar.setTime(dateServer);                                           //设置当前日期
        int nowDate = calendar.get(Calendar.DAY_OF_YEAR);


        ArgUtil.put(ctx, argKey, String.valueOf(nowDate));
    }

    /** 检查本地存储的时间是否包含参数时间的天 */
    public static boolean checkLastLoadDate(Context ctx, String argKey, long timeStamp){
        Date dateServer = new Date(timeStamp);
        Calendar calendar = Calendar.getInstance(); //日历对象
        calendar.setTime(dateServer);   //设置当前日期

        // 最后获取广告时间
        String lastLogDate = ArgUtil.get(ctx, argKey);
        String nowDate = String.valueOf(calendar.get(Calendar.DAY_OF_YEAR));
        return TextUtils.equals(lastLogDate, nowDate);  // 已近记录过
    }


    /** 获取指定的定时关灯指令 */
    @Nullable
    public static MqttFromS<Action> makeMeUsbOff(MqttFromS<Action> mqttFromS){
        if(mqttFromS.data.cmd.targetValue == null) mqttFromS.data.cmd.targetValue = new ArrayList<>();
        mqttFromS.requestId             = UUID.randomUUID().toString();
        mqttFromS.cmd                   = BizConstant.CMD_TYPE_ACT_AUTO;
        mqttFromS.data.requestName      = BizConstant.REQUEST_NAME_AUTO_POWEROFF;
        mqttFromS.data.cmd.targetValue.clear();
        mqttFromS.data.cmd.targetValue.add(BizConstant.REQUEST_NAME_AUTO_POWEROFF_VALUE);
        mqttFromS.targetTime            = System.currentTimeMillis() + BizConstant.POWER_ON_PERIOD;
        return mqttFromS;
    }

    /** 获取测试指令 */
    public static MqttFromS<Action> getTestCmd(Context context, String requestName){
        MqttFromS<Action> actionMqttFromS = new MqttFromS<>();
        actionMqttFromS.requestId               = UUID.randomUUID().toString();
        actionMqttFromS.cmd                     = BizConstant.CMD_TYPE_ACT;
        actionMqttFromS.data                    = new Action();
        actionMqttFromS.data.btName             = "JDY-16";
        actionMqttFromS.data.btId               = BsUtil.getBtId(context);
        actionMqttFromS.data.btPairPWD          = "123456";
        actionMqttFromS.data.requestName        = requestName;

        actionMqttFromS.data.cmd                = App.getApp().getTableMgr().getTbCmd().queryCmdByArgName(requestName);
        return actionMqttFromS;
    }

    /** 获取媒体音量 */
    public static int getMediaVol(Context context){
        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        if(audioManager == null) return -1;
        return audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
    }

    /** 设置媒体音量 */
    public static void setMediaVol(Context context, int vol){
        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        if(audioManager == null) return;
        audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, vol, AudioManager.FLAG_PLAY_SOUND);
    }

    /** 设置媒体音量(比率) */
    public static void setMediaVolRate(Context context, int vol){
        int volReal = (int)(vol/100f * 15);
        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        if(audioManager == null) return;
        audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volReal, AudioManager.FLAG_PLAY_SOUND);
    }

    public static VideoAd getDefaultVideo(){
        VideoAd videoAd = new VideoAd();
        videoAd.indbtime = System.currentTimeMillis();
        videoAd.name = "默认视频";
        videoAd.url = BizConstant.DEFAULT_MOVIE;
        videoAd.state = VideoAd.LOAD_STATE_OK;
        return videoAd;
    }
}
